/* eslint-disable no-nested-ternary */
/* eslint-disable no-plusplus */
/* eslint-disable no-param-reassign */
/* eslint-disable no-unused-expressions */
/* eslint-disable no-underscore-dangle */
/* eslint-disable consistent-return */
/**
 * 异步省市区
 * 墨烦/秦国胜
 * 2021/07/14
 */

import React, { Component } from 'react';
import PropTypes, { any } from 'prop-types';
import { message, Spin, TreeSelect } from 'antd';

import { fetch } from '../../../common/api';
import { log } from '../../../common/tool';

const { SHOW_PARENT, TreeNode } = TreeSelect;

class AjaxTreeSelect extends Component {
    constructor() {
        super();
        this.state = {
            loading: false, // loading
            treeData: [], // 数据
        };
        // 是否已加载
        this.open = true;
    }

    componentDidMount() {
        this.getTreeData();
    }

    componentWillUnmount() {
        this.open = false;
    }

  // 获取数据
  getTreeData = () => {
      const { apiPath, apiData, apiMethod, treeName } = this.props;
      this.setState({
          loading: true,
      });
      fetch({ apiPath, apiData, apiMethod })
          .then((data) => {
              // 判断如果卸载,则不再设置数据
              if (!this.open) return;
              let datas = Array.isArray(data.data) ?
              data.data
              : 
              data.data ? 
                  [ data.data ] 
                  : 
                  []
              this.setState({
                  loading: false,
                  treeData: datas && datas.length ? datas : [],
              });
          })
          .catch((err) => {
              this.setState({
                  loading: false,
              });
              log.error(err);
              message.error(`获取${treeName}失败:${err.message}`);
          });
  };

  // 异步加载数据
  onLoadData = (treeNode) => {
      const {
          apiPath,
          apiParentParams,
          apiParent,
          apiParentVal,
          apiMethod,
          treeChildren,
          treeValueKey,
      } = this.props;
      const { treeData } = this.state;
      const code = treeNode.props[apiParentVal || treeValueKey];
      return new Promise((resolve) => {
          if (treeNode.props[treeChildren] && treeNode.props[treeChildren].length) {
              resolve();
              return;
          }
          const params = {
              ...apiParentParams,
          };
          params[apiParent || treeValueKey] = code;
          fetch({ apiPath, apiData: params, apiMethod })
              .then((res) => {
                  if (res && res.data && res.data.length) {
                      const datas = res.data;
                      const recursion = (list) => {
                          const len = list.length;
                          for (let i = 0; i < len; i++) {
                              if (list[i][treeChildren] && list[i][treeChildren].length) {
                                  //    list[i].isLeaf = true;
                                  recursion(list[i][treeChildren]);
                              } else {
                                  //    list[i].isLeaf = false;
                              }
                              if (list[i][apiParentVal || treeValueKey] === code) {
                                  list[i][treeChildren] = datas;
                                  break;
                              }
                          }
                      };
                      recursion(treeData);
                  }
                  this.setState({
                      treeData,
                  });
                  resolve();
              })
              .catch((err) => {
                  // this.setState({
                  //     loading: true
                  // });
                  log.error(err.message);
              });
      });
  };

  // 处理展示
  renderTreeNodes = (data) => {
      const { treeValueKey, treeNameKey, treeChildren } = this.props;
      return data && data.length
          ? data.map((item) => {
              if (item[treeChildren] && item[treeChildren].length) {
                  return (
                      <TreeNode
                          key={item[treeValueKey]}
                          title={item[treeNameKey]}
                          value={item[treeValueKey]}
                      >
                          {item[treeChildren] && item[treeChildren].length
                              ? this.renderTreeNodes(item[treeChildren])
                              : ''}
                      </TreeNode>
                  );
              }
              return (
                  <TreeNode
                      {...item}
                      key={item[treeValueKey]}
                      title={item[treeNameKey]}
                      value={item[treeValueKey]}
                  />
              );
          })
          : '';
  };

  // 值变化
  onChange = (val, label) => {
      const { onChange, multiple, treeValueKey, treeNameKey } = this.props;
      let changeData = {};
      // console.log('val', val);
      // console.log('label', label);
      if (multiple) {
          changeData = [];
          val.forEach((item, index) => {
              const obj = {};
              obj[treeValueKey] = item;
              obj[treeNameKey] = label[index];
              changeData.push(obj);
          });
      } else {
          changeData[treeValueKey] = val;
          changeData[treeNameKey] = label[0] || '';
      }
      onChange && onChange(changeData);
  };

  render() {
      const { loading, treeData } = this.state;
      const {
          showSearch,
          allowClear,
          value,
          multiple,
          isSelectParent,
          isCheck,
          treeName,
          showCheckedStrategy,
          treeValueKey,
          disabled,
          maxTagCount,
          isOnLoad,
      } = this.props;
      let disposeValue = {};
      if (value) {
          if (multiple && value.length) {
              disposeValue = [];
              value.forEach((item) => {
                  disposeValue.push(item[treeValueKey]);
              });
          } else {
              disposeValue = value[treeValueKey] || undefined;
          }
      }
      // 多选处理
      const propsMultiple = isCheck
          ? {
              treeCheckable: true,
          }
          : {
              multiple,
          };
      // 是否异步按需加载
      const propsOnLoad = isOnLoad
          ? {
              loadData: this.onLoadData,
          }
          : {};
      return (
          <Spin spinning={loading}>
              <div className={isSelectParent ? 'com-tree-select-no-parent' : ''}>
                  <TreeSelect
                      getPopupContainer={(triggerNode) => triggerNode.parentNode}
                      filterTreeNode={(input, option) => {
                          return option.props.title.toLowerCase().indexOf(input.toLowerCase()) >= 0;
                      }}
                      showSearch={showSearch}
                      allowClear={allowClear}
                      disabled={disabled}
                      showCheckedStrategy={showCheckedStrategy}
                      value={disposeValue}
                      placeholder={`选择${treeName}`}
                      notFoundContent={`未找到${treeName}`}
                      onChange={this.onChange}
                      maxTagCount={maxTagCount}
                      {...propsMultiple}
                      {...propsOnLoad}
                  >
                      {this.renderTreeNodes(treeData)}
                  </TreeSelect>
              </div>
          </Spin>
      );
  }
}

AjaxTreeSelect.defaultProps = {
    multiple: false,
    isCheck: false,
    isSelectParent: false,
    isOnLoad: false,
    showSearch: true,
    allowClear: true,
    disabled: false,
    apiData: {}, // 请求参数
    apiParentParams: {},
    showCheckedStrategy: SHOW_PARENT,
    treeChildren: 'children',
};

AjaxTreeSelect.propTypes = {
    apiPath: PropTypes.string.isRequired, // API接口
    apiData: PropTypes.object, // 附加产参数
    apiMethod: PropTypes.string, // api请求method
    treeName: PropTypes.string.isRequired, // 缺省列表名称
    treeValueKey: PropTypes.string.isRequired, // 树表值的key值
    treeNameKey: PropTypes.string.isRequired, // 树表名称key值
    treeChildren: PropTypes.string, // 树表的子级key值， 默认Children
    isOnLoad: PropTypes.bool, // 是否异步加载
    apiParentParams: PropTypes.object, // 异步加载父级参数
    apiParent: PropTypes.string, // 异步加载父级查询参数字段
    apiParentVal: PropTypes.string, // 异步加载父级查询，取值字段

    value: PropTypes.oneOfType([
    // 传递的值
        PropTypes.array,
        PropTypes.object,
    ]),
    onChange: PropTypes.func, // 值变化

    isSelectParent: PropTypes.bool, // 是否父级可选
    multiple: PropTypes.bool, // 是否多选,isNoParent为true,不选择父级
    isCheck: PropTypes.bool, // CheckBocx多选, isNoParent为true无效

    showSearch: PropTypes.bool, // 是否搜索
    allowClear: PropTypes.bool, // 是否显示清除图标
    showCheckedStrategy: any, // 定义选中项回填的方式
    disabled: PropTypes.bool, // 是否禁用
    maxTagCount: PropTypes.number, // 最多显示多少tag
    dropdownStyle: PropTypes.object, // 下拉菜单的样式
};

export default AjaxTreeSelect;
